﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EntityFrameworkETL.SaveBatchedChanges
{
    public interface IFixupCommands
    {
        void Fixup(IEnumerable<int> ids, BatchedCommand batchedCommand);
    }

    public class FixupCommands : IFixupCommands
    {
        public void Fixup(IEnumerable<int> ids, BatchedCommand batchedCommand)
        {
            foreach (var id in ids)
            {
                var structuredCommandCache = batchedCommand.Commands.First(x => !x.CommandCache.IsFixedUp);
                SetId(structuredCommandCache.CommandCache, id);
                SetFks(structuredCommandCache, id);
                structuredCommandCache.CommandCache.IsFixedUp = true;
            }
        }

        public void SetId(CommandCache commandCache, int id)
        {
            var propertyInfo = commandCache.Entity.GetType().GetProperties().Single(x => x.Name == commandCache.PrimaryKeyPropertyName);
            propertyInfo.SetValue(commandCache.Entity, id);
        }

        public void SetFks(StructuredCommandCache structuredCommandCache, int id)
        {
            foreach (var childCommand in structuredCommandCache.ChildCommands)
            {
                foreach (DbParameter parameter in childCommand.CommandCache.DbCommand.Parameters)
                {
                    if (!childCommand.CommandCache.ParameterIsFkDictionary[parameter.ParameterName])
                        continue;  //ignore parameters that are not foreign keys.
                    if (parameter.Value.ToString() == structuredCommandCache.CommandCache.FakeId.ToString(CultureInfo.InvariantCulture))
                    {
                        parameter.Value = id;
                    }
                }
            }
        }
    }
}
